Análisis de los factores que influyen en la decisión de compra de vivienda a nivel internacional

2025-11-06

Ander Castro & Lucas Martinez

1. Introducción

La compra de vivienda es uno de los procesos financieros más importantes para los individuos y familias en todo el mundo. Para la mayoría de compradores, esta adquisición se realiza a través de un préstamo hipotecario, por lo que las instituciones financieras evalúan múltiples factores para determinar si un solicitante es elegible para un crédito y bajo qué condiciones.

El mercado inmobiliario global es un sector clave en la economía, moviendo miles de millones de dólares anualmente. La correcta evaluación del perfil financiero del comprador, junto con las características del inmueble, es fundamental tanto para garantizar el acceso a la vivienda como para reducir el riesgo económico de las entidades financieras.

1.1 Obtención de los datos

El set de datos fue obtenido de la plataforma Kaggle y contiene información global sobre compras de vivienda y decisiones de aprobación hipotecaria. Incluye 200,000 registros (muestras) con 25 variables relacionadas tanto con la propiedad como con el comprador y su historial financiero.

El objetivo principal de este estudio es realizar un análisis estadístico para comprender qué factores influyen en la aprobación o rechazo de un préstamo hipotecario. Asimismo, se buscará identificar qué características del comprador y de la propiedad tienen mayor peso en la decisión final y desarrollar modelos predictivos que permitan anticipar el resultado de aprobación crediticia.

1.2 Metodología

A lo largo de este trabajo, se pretenden analizar las siguientes preguntas:

El análisis se llevará a cabo en dos fases principales:

Volumen 1: Análisis Exploratorio y Estadístico

  1. Importación de librerías y datos
  2. Resumen estadístico general
  3. Visualización de datos
  4. Contraste de hipótesis y estadística inferencial
  5. PCA: Análisis de Componentes Principales
    • Varianza explicada
    • Componentes principales

Volumen 2: Machine Learning

  1. Modelo para la decisión de compra (clasificación)
  2. Modelo para el precio de la vivienda
  3. Interpretación de resultados
  4. Conclusiones y limitaciones
  5. Referencias

1.3 Variables del dataset

El conjunto de datos Global House Purchase Decision Dataset contiene información detallada sobre propiedades residenciales, características del entorno y perfil financiero de los compradores. En total, incluye 200.000 observaciones y 25 variables, que permiten analizar los factores que influyen en la decisión de compra.

A continuación, se describen las variables incluidas en el dataset:

2. Análisis exploratorio de los datos

2.1 Importar datos y librerías

library(dplyr)
library(ggplot2)
library(tidyr)
library(corrplot)
library(scales)
library(broom)
library(car)

data <- read.csv('./global_house_purchase_dataset.csv')
glimpse(data)
## Rows: 200,000
## Columns: 25
## $ property_id             <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,…
## $ country                 <chr> "France", "South Africa", "South Africa", "Ger…
## $ city                    <chr> "Marseille", "Cape Town", "Johannesburg", "Fra…
## $ property_type           <chr> "Farmhouse", "Apartment", "Farmhouse", "Farmho…
## $ furnishing_status       <chr> "Semi-Furnished", "Semi-Furnished", "Semi-Furn…
## $ property_size_sqft      <int> 991, 1244, 4152, 3714, 531, 3169, 1986, 4048, …
## $ price                   <int> 412935, 224538, 745104, 1110959, 99041, 110736…
## $ constructed_year        <int> 1989, 1990, 2019, 2008, 2007, 1985, 1976, 2020…
## $ previous_owners         <int> 6, 4, 5, 1, 6, 0, 1, 4, 6, 2, 4, 2, 4, 6, 6, 1…
## $ rooms                   <int> 6, 8, 2, 3, 3, 5, 2, 6, 2, 5, 8, 3, 2, 7, 3, 8…
## $ bathrooms               <int> 2, 8, 1, 3, 3, 2, 1, 6, 1, 2, 3, 1, 2, 2, 1, 6…
## $ garage                  <int> 1, 1, 1, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0…
## $ garden                  <int> 1, 1, 1, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1…
## $ crime_cases_reported    <int> 1, 1, 0, 0, 3, 0, 0, 1, 0, 0, 1, 4, 2, 6, 0, 1…
## $ legal_cases_on_property <int> 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1…
## $ customer_salary         <int> 10745, 16970, 21914, 17980, 17676, 95520, 1142…
## $ loan_amount             <int> 193949, 181465, 307953, 674720, 65833, 793316,…
## $ loan_tenure_years       <int> 15, 20, 30, 15, 25, 30, 25, 20, 15, 10, 25, 20…
## $ monthly_expenses        <int> 6545, 8605, 2510, 8805, 8965, 10615, 14440, 72…
## $ down_payment            <int> 218986, 43073, 437151, 436239, 33208, 314052, …
## $ emi_to_income_ratio     <dbl> 0.16, 0.08, 0.09, 0.33, 0.03, 0.05, 0.16, 0.13…
## $ satisfaction_score      <int> 1, 9, 6, 2, 3, 10, 9, 1, 8, 1, 8, 2, 3, 6, 1, …
## $ neighbourhood_rating    <int> 5, 1, 8, 6, 3, 8, 10, 5, 8, 4, 7, 5, 7, 9, 2, …
## $ connectivity_score      <int> 6, 2, 1, 6, 4, 2, 10, 8, 10, 7, 6, 6, 2, 1, 7,…
## $ decision                <int> 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0…
sum(is.na(data))
## [1] 0
sum(duplicated(data))
## [1] 0

2.2 Resumen estadístico general

data %>%
  select_if(is.numeric) %>%
  summary()
##   property_id     property_size_sqft     price         constructed_year
##  Min.   :     1   Min.   : 400       Min.   :  56288   Min.   :1960    
##  1st Qu.: 50001   1st Qu.:1802       1st Qu.: 565990   1st Qu.:1975    
##  Median :100001   Median :3190       Median :1023429   Median :1991    
##  Mean   :100001   Mean   :3196       Mean   :1215365   Mean   :1991    
##  3rd Qu.:150000   3rd Qu.:4589       3rd Qu.:1725556   3rd Qu.:2008    
##  Max.   :200000   Max.   :6000       Max.   :4202732   Max.   :2023    
##  previous_owners     rooms         bathrooms        garage      
##  Min.   :0.000   Min.   :1.000   Min.   :1.00   Min.   :0.0000  
##  1st Qu.:1.000   1st Qu.:3.000   1st Qu.:1.00   1st Qu.:0.0000  
##  Median :3.000   Median :5.000   Median :2.00   Median :0.0000  
##  Mean   :3.001   Mean   :4.514   Mean   :2.76   Mean   :0.4994  
##  3rd Qu.:5.000   3rd Qu.:7.000   3rd Qu.:4.00   3rd Qu.:1.0000  
##  Max.   :6.000   Max.   :8.000   Max.   :8.00   Max.   :1.0000  
##      garden       crime_cases_reported legal_cases_on_property customer_salary 
##  Min.   :0.0000   Min.   : 0.000       Min.   :0.0000          Min.   :  2000  
##  1st Qu.:0.0000   1st Qu.: 0.000       1st Qu.:0.0000          1st Qu.: 21450  
##  Median :1.0000   Median : 1.000       Median :0.0000          Median : 41465  
##  Mean   :0.5002   Mean   : 1.229       Mean   :0.2489          Mean   : 46529  
##  3rd Qu.:1.0000   3rd Qu.: 2.000       3rd Qu.:0.0000          3rd Qu.: 70805  
##  Max.   :1.0000   Max.   :10.000       Max.   :1.0000          Max.   :100000  
##   loan_amount      loan_tenure_years monthly_expenses  down_payment    
##  Min.   :  23504   Min.   :10.00     Min.   :  500    Min.   :   8966  
##  1st Qu.: 337280   1st Qu.:15.00     1st Qu.: 5770    1st Qu.: 184959  
##  Median : 626932   Median :20.00     Median :10520    Median : 356170  
##  Mean   : 759758   Mean   :19.99     Mean   :10560    Mean   : 455607  
##  3rd Qu.:1058416   3rd Qu.:25.00     3rd Qu.:15260    3rd Qu.: 625735  
##  Max.   :3520150   Max.   :30.00     Max.   :20000    Max.   :2492723  
##  emi_to_income_ratio satisfaction_score neighbourhood_rating connectivity_score
##  Min.   :0.0000      Min.   : 1.000     Min.   : 1.000       Min.   : 1.000    
##  1st Qu.:0.0700      1st Qu.: 3.000     1st Qu.: 3.000       1st Qu.: 3.000    
##  Median :0.1300      Median : 5.000     Median : 5.000       Median : 5.000    
##  Mean   :0.1954      Mean   : 5.499     Mean   : 5.505       Mean   : 5.496    
##  3rd Qu.:0.2400      3rd Qu.: 8.000     3rd Qu.: 8.000       3rd Qu.: 8.000    
##  Max.   :3.4600      Max.   :10.000     Max.   :10.000       Max.   :10.000    
##     decision     
##  Min.   :0.0000  
##  1st Qu.:0.0000  
##  Median :0.0000  
##  Mean   :0.2303  
##  3rd Qu.:0.0000  
##  Max.   :1.0000
sapply(data %>% select(where(is.character)), n_distinct)
##           country              city     property_type furnishing_status 
##                13                40                 6                 3

2.3 Visualización de datos

Distribución de la variable decision

data %>%
  count(decision) %>%
  mutate(pct = n/sum(n)*100,
         decision = factor(decision, labels = c("No compra", "Compra"))) %>%
  ggplot(aes(x = decision, y = pct, fill = decision)) +
  geom_col() +
  geom_text(aes(label = sprintf("%.2f%%", pct)), 
            vjust = 1.5, color = "black", size = 4) +
  labs(title = "Distribución de la decisión de compra",
       x = "Decisión", y = "%") +
  scale_fill_manual(values = c("#F8766D", "#00BA38")) +
  theme_minimal() +
  theme(legend.position = "none")

El gráfico representa la distribución porcentual de la variable decision, que indica si un cliente decide o no comprar una vivienda. Se observa un desequilibrio marcado entre ambas categorías: el 76.97% de los individuos no realiza la compra, mientras que solo el 23.03% decide concretarla.

Esta distribución desequilibrada es un aspecto importante a considerar, ya que puede influir en el rendimiento de los modelos predictivos.

Distribución del precio

ggplot(data, aes(x = price)) +
  geom_histogram(fill = "#69b3a2", color = "white", bins = 40) +
  scale_x_continuous(labels = comma) +
  labs(title = "Distribución del precio de las viviendas",
  x = "Precio (USD)", y = "Frecuencia") +
  theme_minimal()

El histograma muestra la distribución del precio de las viviendas en dólares estadounidenses (USD). Se observa una distribución asimétrica a la derecha, parecida a una distribución gamma, lo que indica que la mayoría de los inmuebles se concentran en los rangos de precios más bajos, mientras que un número reducido de propiedades presenta precios considerablemente más altos.

La mayor frecuencia de viviendas se sitúa aproximadamente entre los 500,000 y 1,000,000 USD, reflejando que este rango constituye el segmento más representativo del mercado analizado. A partir de valores superiores a los 2 millones de dólares, la frecuencia disminuye progresivamente, mostrando la presencia de propiedades de lujo que elevan la cola derecha de la distribución.

A continuación, aplicaremos una transformación logarítmica al precio con el objetivo de aproximar su distribución a una normal.

data <- data %>% mutate(log_price = log(price))

ggplot(data, aes(x = log_price)) +
  geom_histogram(fill = "#69b3a2", color = "white", bins = 40) +
  scale_x_continuous() +
  labs(title = "Distribución del logaritmo del precio de las viviendas",
  x = "Precio (USD)", y = "Frecuencia") +
  theme_minimal()

Tras aplicar la transformación logarítmica al precio de las viviendas, se observa que la distribución se aproxima más a una distribución normal, corrigiendo la fuerte asimetría a la derecha presente en los valores originales.

Distribución del precio por país y por tipo de propiedad

# Boxplot de precios por país
data %>%
  ggplot(aes(x = country, y = price)) +
  geom_boxplot(fill = "#56B4E9", outlier.alpha = 0.2) +
  coord_flip() +
  scale_y_continuous(labels = comma) +
  labs(title = "Distribución del precio por país (Top 10)",
       x = "País", y = "Precio (USD)") +
  theme_minimal()

En este gráfico se aprecia que Singapur, Emiratos Árabes Unidos (UAE), Japón y Estados Unidos presentan los precios medianos más altos, así como una mayor dispersión, lo que refleja mercados con viviendas de alto valor y mayor desigualdad de precios. En contraste, países como Brasil, India y Sudáfrica muestran precios sustancialmente más bajos y con menor variabilidad, indicando mercados más accesibles y homogéneos.

# Boxplot de precios por tipo de propiedad

data %>%
  ggplot(aes(x = property_type, y = price)) +
  geom_boxplot(fill = "#56B4E9", outlier.alpha = 0.2) +
  scale_y_continuous(labels = comma) +
  coord_flip() +
  labs(title = "Distribución del precio por tipo de propiedad (Top 10)",
       x = "Propiedad", y = "Precio (USD)") +
  theme_minimal()

Por otro lado, el boxplot por tipo de propiedad evidencia que no hay diferencias estructurales dentro de cada mercado. Si bien es cierto que hay propiedades muy caras (outliers) en todos los tipos de propiedades, las distribuciones centrales son bastante similares, sin diferencias estructurales marcadas entre categorías.

Relaciones entre variables numéricas

# Seleccionar variables numéricas relevantes

num_vars <- data %>%
  select_if(is.numeric) %>%
  select(-property_id)

# Matriz de correlación

corr_matrix <- cor(num_vars)

corrplot(corr_matrix, method = "color", type = "upper", tl.col = "black", order = "hclust")

El análisis de las relaciones entre las variables numéricas revela patrones coherentes con el comportamiento esperado en un contexto inmobiliario.

En primer lugar, se observa una correlación positiva entre el precio de la vivienda y el tamaño del inmueble (property_size_sqft), lo cual es lógico, ya que las propiedades de mayor superficie tienden a tener precios más altos.

Asimismo, variables como el salario del comprador (customer_salary), la cantidad inicial que el comprador aporta (down_payment) y el monto del préstamo (loan_amount) muestran también una relación directa con el precio, reflejando que los compradores con mayor capacidad económica tienden a adquirir viviendas más costosas.

En cuanto a correlaciones negativas, vemos una relación lógica entre customer_salary y emi_to_income_ratio: cuanto mayor es el salario del comprador, menor es la proporción que representa la cuota mensual del préstamo respecto a sus ingresos. Esto es coherente, ya que un ingreso alto diluye el peso relativo de la cuota hipotecaria, mejorando la capacidad de pago.

Además, existe una correlación negativa interesante entre legal_cases_on_property y decision. Esto significa que, a medida que aumentan los casos legales asociados a una propiedad, disminuye la probabilidad de que la decisión final sea positiva (compra aprobada).

Relaciones bivariantes

# Salario vs Decisión de compra
data %>%
  mutate(decision = factor(decision, labels = c("No compra", "Compra"))) %>%
  ggplot(aes(x = decision, y = customer_salary, fill = decision)) +
  geom_boxplot(outlier.alpha = 0.2) +
  scale_fill_manual(values = c("#F8766D", "#00BA38")) +
  labs(title = "Salario según decisión de compra",
  x = "Decisión", y = "Salario del cliente") +
  theme_minimal() +
  theme(legend.position = "none")

# Número de crímenes reportados vs Precio medio
data %>%
  group_by(crime_cases_reported) %>%
  summarise(mean_price = mean(price, na.rm = TRUE)) %>%
  ggplot(aes(x = factor(crime_cases_reported), y = mean_price)) +
  geom_col(fill = "#56B4E9") +
  scale_y_continuous(labels = comma) +
  labs(title = "Precio medio según el número de crímenes reportados",
  x = "Número de crímenes", y = "Precio medio (USD)") +
  theme_minimal()

El análisis de las relaciones bivariantes permite identificar cómo ciertas variables influyen directamente en la decisión de compra y en el precio de la vivienda.

En primer lugar, se observa que el salario del cliente (customer_salary) presenta una relación positiva con la decisión de compra.

Por otra parte, la relación entre el número de crímenes reportados (crime_cases_reported) y el precio medio de las viviendas muestra una tendencia inversa: los precios disminuyen a medida que aumenta la incidencia delictiva.

Decisión de compra por país

# ¿Qué porcentaje de personas toma la decisión de comprar una vivienda en cada país?
data %>%
  group_by(country) %>%
  summarise(pct_purchase = mean(decision) * 100) %>%
  arrange(desc(pct_purchase)) %>%
  slice_head(n = 10) %>%
  ggplot(aes(x = reorder(country, pct_purchase), y = pct_purchase)) +
  geom_col(fill = "#009E73") +
  geom_text(aes(label = sprintf("%.2f%%", pct_purchase)), 
            hjust = 1.2, color = "white", size = 4) +
  coord_flip() +
  labs(title = "Porcentaje de decisión de compra por país (Top 10)",
  x = "País", y = "% de compras") +
  theme_minimal()

El análisis de la decisión de compra por país revela diferencias significativas en el comportamiento de los compradores según su ubicación geográfica.

Se observa que algunos países presentan una mayor proporción de decisiones de compra positivas, lo que puede estar relacionado con factores como la estabilidad económica, el nivel de ingresos promedio o las características del mercado inmobiliario local.

3. Contraste de hipótesis y estadística inferencial

En esta sección se pretende verificar estadísticamente algunas de las relaciones sugeridas en el análisis exploratorio previo. Para ello, se formulan hipótesis estadísticas y se aplican pruebas de contraste adecuadas según el tipo de variable y la distribución observada.

3.1 Diferencias de precio entre países

Hipótesis:

# Test de normalidad
shapiro.test(sample(data$log_price, 5000))
## 
##  Shapiro-Wilk normality test
## 
## data:  sample(data$log_price, 5000)
## W = 0.96749, p-value < 2.2e-16

El test de Shapiro–Wilk, aplicado a una muestra aleatoria de la variable log_price, muestra un p-value < 2.2e-16, lo que sugiere que la variable transformada no sigue una distribución normal perfecta. No obstante, dado el gran tamaño muestral, el ANOVA resulta suficientemente robusto frente a desviaciones de normalidad, por lo que la ligera falta de ajuste no compromete la validez del análisis.

A continuación, se realiza la prueba de Levene para ver si las varianzas entre países son homogéneas o no, y esto nos indicará si podemos utilizar el test paramétrico de ANOVA o, en caso contrario, el de Kruskal-Wallis.

# Test de homogeneidad de varianzas
leveneTest(log_price ~ factor(country), data = data)
## Levene's Test for Homogeneity of Variance (center = median)
##           Df F value Pr(>F)
## group     12  1.4727  0.126
##       199987

El resultado (p = 0.126) sugiere que no existe evidencia suficiente para rechazar la hipótesis nula de igualdad de varianzas, cumpliéndose así el supuesto de homocedasticidad. Por ello, se aplicó un ANOVA clásico para comparar el precio medio entre países usando la variable transformada.

# ANOVA
anova_country <- aov(log_price ~ factor(country), data = data)
summary(anova_country)
##                     Df Sum Sq Mean Sq F value Pr(>F)    
## factor(country)     12  38869    3239    7414 <2e-16 ***
## Residuals       199987  87373       0                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

El ANOVA realizado sobre el precio de la vivienda en su escala logarítmica revela diferencias estadísticamente significativas entre países. El modelo muestra un p-value < 2e-16, lo que indica que la variación del precio medio de las viviendas difiere de forma sustancial según el país.

Ahora llevaremos a cabo el test de Tukey para ver qué países difieren entre sí en el precio medio. Este test incluye una corrección automática del error familiar (FWER), garantizando que la probabilidad de obtener falsos positivos se mantenga controlada al realizar múltiples comparaciones simultáneas.

# Post-hoc Tukey
tukey <- TukeyHSD(anova_country)
tukey
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = log_price ~ factor(country), data = data)
## 
## $`factor(country)`
##                               diff         lwr         upr p adj
## Brazil-Australia       -0.47616460 -0.50110219 -0.45122702 0e+00
## Canada-Australia        0.07412258  0.04918662  0.09905854 0e+00
## China-Australia         0.17005499  0.14517333  0.19493665 0e+00
## France-Australia        0.26375468  0.23890955  0.28859980 0e+00
## Germany-Australia      -0.07306215 -0.09799528 -0.04812902 0e+00
## India-Australia        -0.76989040 -0.79484424 -0.74493656 0e+00
## Japan-Australia         0.32866878  0.30369861  0.35363896 0e+00
## Singapore-Australia     0.77667016  0.75168399  0.80165633 0e+00
## South Africa-Australia -0.59123686 -0.61617282 -0.56630089 0e+00
## UAE-Australia           0.61147800  0.58643507  0.63652092 0e+00
## UK-Australia            0.21916180  0.19423070  0.24409290 0e+00
## USA-Australia           0.44443000  0.41944507  0.46941494 0e+00
## Canada-Brazil           0.55028718  0.52533303  0.57524134 0e+00
## China-Brazil            0.64621959  0.62131970  0.67111948 0e+00
## France-Brazil           0.73991928  0.71505590  0.76478266 0e+00
## Germany-Brazil          0.40310245  0.37815114  0.42805377 0e+00
## India-Brazil           -0.29372580 -0.31869781 -0.26875378 0e+00
## Japan-Brazil            0.80483339  0.77984505  0.82982172 0e+00
## Singapore-Brazil        1.25283476  1.22783044  1.27783908 0e+00
## South Africa-Brazil    -0.11507225 -0.14002640 -0.09011810 0e+00
## UAE-Brazil              1.08764260  1.06258156  1.11270363 0e+00
## UK-Brazil               0.69532640  0.67037711  0.72027570 0e+00
## USA-Brazil              0.92059461  0.89559152  0.94559769 0e+00
## China-Canada            0.09593241  0.07103414  0.12083067 0e+00
## France-Canada           0.18963210  0.16477034  0.21449385 0e+00
## Germany-Canada         -0.14718473 -0.17213443 -0.12223504 0e+00
## India-Canada           -0.84401298 -0.86898338 -0.81904259 0e+00
## Japan-Canada            0.25454620  0.22955949  0.27953292 0e+00
## Singapore-Canada        0.70254758  0.67754488  0.72755028 0e+00
## South Africa-Canada    -0.66535944 -0.69031197 -0.64040691 0e+00
## UAE-Canada              0.53735541  0.51229599  0.56241484 0e+00
## UK-Canada               0.14503922  0.12009154  0.16998689 0e+00
## USA-Canada              0.37030742  0.34530595  0.39530889 0e+00
## France-China            0.09369969  0.06889240  0.11850698 0e+00
## Germany-China          -0.24311714 -0.26801256 -0.21822171 0e+00
## India-China            -0.93994539 -0.96486156 -0.91502922 0e+00
## Japan-China             0.15861380  0.13368127  0.18354632 0e+00
## Singapore-China         0.60661517  0.58166663  0.63156372 0e+00
## South Africa-China     -0.76129184 -0.78619011 -0.73639358 0e+00
## UAE-China               0.44142301  0.41641762  0.46642840 0e+00
## UK-China                0.04910681  0.02421341  0.07400021 0e+00
## USA-China               0.27437502  0.24942770  0.29932233 0e+00
## Germany-France         -0.33681683 -0.36167574 -0.31195792 0e+00
## India-France           -1.03364508 -1.05852477 -1.00876539 0e+00
## Japan-France            0.06491411  0.04001804  0.08981017 0e+00
## Singapore-France        0.51291548  0.48800337  0.53782759 0e+00
## South Africa-France    -0.85499153 -0.87985329 -0.83012978 0e+00
## UAE-France              0.34772332  0.32275428  0.37269235 0e+00
## UK-France              -0.04459288 -0.06944976 -0.01973600 2e-07
## USA-France              0.18067533  0.15576445  0.20558620 0e+00
## India-Germany          -0.69682825 -0.72179582 -0.67186069 0e+00
## Japan-Germany           0.40173094  0.37674705  0.42671482 0e+00
## Singapore-Germany       0.84973231  0.82473244  0.87473218 0e+00
## South Africa-Germany   -0.51817470 -0.54312440 -0.49322501 0e+00
## UAE-Germany             0.68454015  0.65948355  0.70959675 0e+00
## UK-Germany              0.29222395  0.26727911  0.31716879 0e+00
## USA-Germany             0.51749216  0.49249351  0.54249080 0e+00
## Japan-India             1.09855919  1.07355463  1.12356375 0e+00
## Singapore-India         1.54656056  1.52154003  1.57158109 0e+00
## South Africa-India      0.17865355  0.15368315  0.20362394 0e+00
## UAE-India               1.38136840  1.35629118  1.40644561 0e+00
## UK-India                0.98905220  0.96408666  1.01401774 0e+00
## USA-India               1.21432041  1.18930110  1.23933971 0e+00
## Singapore-Japan         0.44800138  0.42296456  0.47303820 0e+00
## South Africa-Japan     -0.91990564 -0.94489236 -0.89491892 0e+00
## UAE-Japan               0.28280921  0.25771575  0.30790267 0e+00
## UK-Japan               -0.10950699 -0.13448885 -0.08452512 0e+00
## USA-Japan               0.11576122  0.09072563  0.14079681 0e+00
## South Africa-Singapore -1.36790702 -1.39290972 -1.34290431 0e+00
## UAE-Singapore          -0.16519216 -0.19030154 -0.14008278 0e+00
## UK-Singapore           -0.55750836 -0.58250622 -0.53251051 0e+00
## USA-Singapore          -0.33224016 -0.35729170 -0.30718861 0e+00
## UAE-South Africa        1.20271485  1.17765543  1.22777427 0e+00
## UK-South Africa         0.81039865  0.78545098  0.83534633 0e+00
## USA-South Africa        1.03566686  1.01066539  1.06066833 0e+00
## UK-UAE                 -0.39231620 -0.41737078 -0.36726161 0e+00
## USA-UAE                -0.16704799 -0.19215614 -0.14193984 0e+00
## USA-UK                  0.22526821  0.20027158  0.25026483 0e+00
sum(tukey[["factor(country)"]][, "p adj"]>0.05)
## [1] 0

El test post-hoc de Tukey mostró diferencias significativas entre todos los pares de países (p-value < 0.05), confirmando que el país de localización es un factor determinante en el precio de la vivienda.

3.2 Factores que influyen en la decisión de compra

data$decision <- as.factor(data$decision)

model1 <- glm(decision ~ log_price + factor(country) +
                satisfaction_score + bathrooms + rooms +
                previous_owners, data
              = data, family = binomial)

summary(model1)
## 
## Call:
## glm(formula = decision ~ log_price + factor(country) + satisfaction_score + 
##     bathrooms + rooms + previous_owners, family = binomial, data = data)
## 
## Coefficients:
##                               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)                 -2.071e+00  1.445e-01 -14.338  < 2e-16 ***
## log_price                   -3.119e-01  1.035e-02 -30.145  < 2e-16 ***
## factor(country)Brazil       -9.601e-01  3.608e-02 -26.608  < 2e-16 ***
## factor(country)Canada       -2.306e-02  3.437e-02  -0.671   0.5024    
## factor(country)China        -7.392e-03  3.430e-02  -0.215   0.8294    
## factor(country)France       -2.761e-02  3.441e-02  -0.802   0.4223    
## factor(country)Germany      -8.422e-03  3.427e-02  -0.246   0.8059    
## factor(country)India        -6.797e-01  3.579e-02 -18.992  < 2e-16 ***
## factor(country)Japan        -6.311e-02  3.464e-02  -1.822   0.0684 .  
## factor(country)Singapore    -2.200e-01  3.584e-02  -6.138 8.38e-10 ***
## factor(country)South Africa -9.945e-01  3.616e-02 -27.505  < 2e-16 ***
## factor(country)UAE          -1.008e-01  3.529e-02  -2.855   0.0043 ** 
## factor(country)UK            2.721e-03  3.440e-02   0.079   0.9369    
## factor(country)USA          -6.912e-01  3.606e-02 -19.166  < 2e-16 ***
## satisfaction_score           7.879e-01  3.956e-03 199.167  < 2e-16 ***
## bathrooms                   -3.584e-03  4.799e-03  -0.747   0.4551    
## rooms                        3.335e-05  3.849e-03   0.009   0.9931    
## previous_owners              4.900e-03  3.441e-03   1.424   0.1544    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 215875  on 199999  degrees of freedom
## Residual deviance: 131859  on 199982  degrees of freedom
## AIC: 131895
## 
## Number of Fisher Scoring iterations: 6
coef_plot <- tidy(model1) %>%
  filter(term != "(Intercept)") %>%
  mutate(signif = ifelse(p.value < 0.05, "*", ""),
         term = paste0(term, signif),
         term = reorder(term, estimate))

ggplot(coef_plot, aes(x = term, y = estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = estimate - std.error, ymax =
                      estimate + std.error),
                width = 0.2) +
  coord_flip() +
  theme_minimal() +
  labs(title = "Efecto de las variables en la probabilidad de
       compra",
       x = "Variables", y = "Coeficiente")

El modelo de regresión logística muestra que la decisión de compra está influida principalmente por el precio de la vivienda (en su escala logarítmica), el país donde se ubica el inmueble y el nivel de satisfacción del comprador. En particular, se observa que el coeficiente de log_price es negativo y altamente significativo (p-value < 2e-16), lo que indica que, a medida que el precio aumenta, la probabilidad de que el comprador decida adquirir la vivienda disminuye. Este resultado sugiere que la capacidad económica es un factor limitante importante en la decisión.

La variable satisfaction_score presenta un efecto positivo y muy significativo (p-value < 2e-16), implicando que un mayor nivel de satisfacción incrementa considerablemente la probabilidad de compra. Este resultado destaca el papel de la percepción personal y la valoración emocional del inmueble en la toma de decisiones, además de los factores económicos.

En cuanto al país de residencia, se identifican diferencias significativas entre mercados. Los compradores en Brasil, India, Sudáfrica, Singapur, Emiratos Árabes Unidos y Estados Unidos presentan probabilidades de compra significativamente menores en comparación con el país de referencia (Australia).

Por el contrario, variables relacionadas con las características físicas del inmueble —como el número de baños (bathrooms), de habitaciones (rooms) o de propietarios anteriores (previous_owners)— no muestran efectos estadísticamente significativos cuando se controlan las demás variables del modelo.

4. PCA: Análisis de Componentes Principales

El análisis de componentes principales (PCA) es clave para identificar los factores que explican la mayor parte de la variabilidad en nuestro conjunto de datos.

# PCA no admite factores ni variables categóricas
pca_data <- data %>%
  select(property_size_sqft, price, log_price,constructed_year,
         previous_owners, rooms, bathrooms, garage, garden,
         crime_cases_reported, legal_cases_on_property,
         customer_salary, loan_amount, loan_tenure_years,
         monthly_expenses, down_payment, emi_to_income_ratio,
         satisfaction_score, neighbourhood_rating,
         connectivity_score)

pca_result <- prcomp(pca_data, scale. = TRUE)
summary(pca_result)
## Importance of components:
##                           PC1     PC2     PC3    PC4     PC5     PC6     PC7
## Standard deviation     2.0942 1.27540 1.26397 1.0120 1.01148 1.00432 1.00271
## Proportion of Variance 0.2193 0.08133 0.07988 0.0512 0.05116 0.05043 0.05027
## Cumulative Proportion  0.2193 0.30061 0.38049 0.4317 0.48285 0.53328 0.58356
##                            PC8     PC9    PC10    PC11    PC12    PC13    PC14
## Standard deviation     1.00140 1.00018 0.99891 0.99848 0.99727 0.99482 0.93835
## Proportion of Variance 0.05014 0.05002 0.04989 0.04985 0.04973 0.04948 0.04403
## Cumulative Proportion  0.63370 0.68371 0.73360 0.78345 0.83318 0.88266 0.92669
##                           PC15    PC16    PC17    PC18   PC19      PC20
## Standard deviation     0.66991 0.61111 0.56839 0.47014 0.3161 1.081e-14
## Proportion of Variance 0.02244 0.01867 0.01615 0.01105 0.0050 0.000e+00
## Cumulative Proportion  0.94913 0.96780 0.98395 0.99500 1.0000 1.000e+00
varianza_explicada <- pca_result$sdev^2 /sum(pca_result$sdev^2)
varianza_acumulada <- cumsum(varianza_explicada)

df_varianza <- data.frame(
  Componente = 1:length(varianza_acumulada),
  Varianza_Acumulada = varianza_acumulada
)

ggplot(df_varianza, aes(x = Componente, y = Varianza_Acumulada)) +
  geom_line(color = "#0072B2", linewidth = 1) +
  geom_point(color = "#0072B2", size = 2) +
  geom_hline(yintercept = 0.80, linetype = "dashed", color = "red") +
  theme_minimal() +
  labs(title = "Varianza explicada acumulada",
       x = "Número de Componentes",
       y = "Varianza Acumulada") +
  scale_x_continuous(breaks = df_varianza$Componente)

Los resultados indican que el primer componente principal (PC1) captura una porción significativa de la varianza total, alrededor del 20%. Además, los primeros diez componentes en conjunto explican cerca del 70–75% de la variabilidad del conjunto de datos.

# Extraer scores de las dos primeras componentes
scores <- as.data.frame(pca_result$x[,1:2])
scores$country <- data$country

ggplot() +
  geom_point(data = scores, aes(x = PC1, y = PC2, color =
                                  country), alpha = 0.6) +
  theme_minimal() +
  labs(title = "Primeras dos componentes del PCA",
       x = "PC1",
       y = "PC2",
       color = "País")

# Qué variables contribuyen a PC1 y PC2
loadings <- as.data.frame(pca_result$rotation[,1:2])
loadings$variable <- rownames(loadings)

# Contribución para PC1
PC1_contrib_df <- loadings %>%
  select(PC1) %>%
  arrange(desc(PC1))

# Contribución para PC2
PC2_contrib_df <- loadings %>%
  select(PC2) %>%
  arrange(desc(PC2))

head(PC1_contrib_df, 5)
##                          PC1
## price              0.4666070
## log_price          0.4553414
## loan_amount        0.4365345
## property_size_sqft 0.4033568
## down_payment       0.3986256
head(PC2_contrib_df, 5)
##                              PC2
## rooms                0.705867249
## bathrooms            0.705777174
## emi_to_income_ratio  0.037967025
## property_size_sqft   0.009998963
## crime_cases_reported 0.009534732

PC1 está fuertemente asociado con el nivel económico y el tamaño de la propiedad. Las variables financieras (precio, cantidad de préstamo, pago inicial) y el tamaño del inmueble tienen cargas altas y positivas, lo que indica que este componente captura principalmente un gradiente de propiedades de mayor costo y mayor superficie frente a propiedades más económicas y pequeñas.

PC2 está dominado casi exclusivamente por la estructura interna del inmueble (número de habitaciones y baños). Estos dos atributos se mueven prácticamente de forma conjunta y definen la configuración habitacional del inmueble, independientemente del precio total.